﻿namespace 进制基础
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 十进制: 逢10进1
            // 高级语言的称谓，其中之一就是能更好读懂。所以在使用高级语言，进行编程中，
            //      我们常用的还是 10 进制。毕竟是高级语言。 
            /*
             *  因为计算机底层使用的是二进制，而二进制转化为十进制较麻烦，不够直观。
                但二进制转化为 八进制 或 十六进制 十分方便，
                3 位二进制可转化为 1 位八进制，
                4 位二进制可转化为 1 位十六进制。

                为什么偏偏是16或8进制，而不其它的，诸如 9 或 20 进制呢？
                2、8、16，分别是 2 的 1 次方，3 次方，4 次方。这一点使得三种进制之间可以非常直接地互相转换。
                8 进制或 16 进制缩短了二进制数，但保持了二进制数的表达特点。
             */
            int dec1 = 9;
            int dec2 = 1;
            int dec3 = dec1 + dec2;

            // 二进制: 逢2进1 （PPT介绍）
            /*
             * 这主要的原因由计算机的硬件有关，组成计算机系统的的逻辑电路只有两种状态，
             *      （接通和断开），只有两种发生的可能。
               1. 当我们的计算机受到干扰的时候，任然能清楚的识别出逻辑电路的状态（接通和断开）。
               2. 所以在具体的系统实现中，二进制的数据表达具有抗干扰能力强的优点。
               3. 相比之下，十进制设计的状态电路就有十种状态的电路，具体的系统实现会变得非常的负责，
                    在判断中出现错误的可能性几率会大大增大。
             */
            byte b4 = 0b01111111;
            byte b5 = 0b00000001;
            byte b6 = (byte)(b4 + b5);
            Console.WriteLine($"b6: {b6}");

            // 八进制: 逢8进1
            // 一种以8为基数的计数法，采用 0，1，2，3，4，5，6，7八个数字，逢八进1。现在用的比较少
            /*
             * 优点: 
             *  容易从字符 parse（使用 ASCII 时直接 char 减掉 0x30 就是其单一位数值），
                容易转字符串（单一位数值加 0x30 就是对应的字符的 ASCII 值）
                容易从字符串 parse（直接移位再加就行…）

            例如，你遇到一个八进制的数，要将其转化成比如说 int 类型的，不断读取字符，减 0x30，
                    加上已有的结果左移 3 位的结果就行了，这里比使用十进制时的结果快…
                    二进制数据量太大，十进制计算太麻烦，十六进制解析太麻烦，八进制在这里正好。
             */
            int octal1 = 07; // 八进制表示的数字 123(88)
            int octal2 = 01;
            int octal3 = octal1 + octal2;
            Console.WriteLine($"octal3 = {octal3}"); // 输出 8

            // 十六进制: 逢16进1 0-9，A B C D E F
            // 它由 0-9，A-F 组成，字母不区分大小写。与 10 进制的对应关系是:
            //      0-9 对应0-9; A-F 对应 10-15。N进制的数可以用 0~(N - 1) 的数表示，超过 9 的用字母 A-F。
            /*
             *  1、用于计算机领域的一种重要的数制 　　
                2、对计算机理论的描述，计算机硬件电路的设计都是很有益的。
                        比如逻辑电路设计中，既要考虑功能的完备，还要考虑用尽可能少的硬件，
                        十六进制就能起到一些理论分析的作用。
                        比如四位二进制电路，最多就是十六种状态，也就是一种十六进制形式，
                        只有这十六种状态都被用上了或者尽可能多的被用上，硬件资源才发挥了尽可能大的作用。 　　
                3、十六进制更简短，因为换算的时候一位16进制数可以顶 4 位 二进制数。

            重要应用 - 内存:
            一个内存地址存着一个对应的值， 内存就相当于(addr,val)的大 hash 表(唯一)，c 语句的语义基本就是改变 hash 值。
            如 int i = 3; 
            假设 i 的内存地址为 0x8049320 ,那么这句话的语义是 0x8049320 = 3，经过 i = 3 后，i  为 (0x8049320,3)
             */
            int hex1 = 0x01;
            int hex3 = 0x0F;
            Console.WriteLine($"hex3: {hex3}");
            int hex4 = hex1 + hex3;
            Console.WriteLine($"hex4: {hex4}");

            var int1 = Convert.ToInt32("1000101", 2); //二进制数 100111101 转成十进制
            var int2 = Convert.ToInt32("105", 8);        //八进数 76 制转成十进制
            var int3 = Convert.ToInt32("FF", 16);       // 16进数 FF 制转换成十进制
            Console.WriteLine($"int1={int1}, int2={int2}, int3={int3}");

            var str1 = Convert.ToString(69, 2); //十进制数 69 转二进制
            var str2 = Convert.ToString(69, 8); //十进制数 69 转八进制
            var str3 = Convert.ToString(255, 16);//十进制数 69 转十六进制
            Console.WriteLine($"str1={str1}, str2={str2}, str3={str3.ToUpper()}, str3={str3.ToUpper()}");
        }
    }
}
